import { Component, OnInit } from '@angular/core';
import { StoreService } from '../store.service';
import { DataService } from '../data.service';
import notify from 'devextreme/ui/notify';
import {
  Condition,
  Aggregation,
  Statistic,
  StatisticTerm,
  ConditionGroup,
  DataPoint,
  QueryPackage,
} from '../classes';
import fileSaver from 'file-saver';
@Component({
  selector: 'app-aggregation',
  templateUrl: './aggregation.component.html',
  styleUrls: ['./aggregation.component.less'],
})
export class AggregationComponent implements OnInit {
  constructor(public store: StoreService, public ds: DataService) {
    this.showconditionlist = false;
  }

  ngOnInit() {}
  popupVisible: boolean = false;
  showconditionlist: boolean = false;
  showstatisticlist: boolean = false;

  clickAddConditionButton: boolean = false;
  clickAddStatisticButton: boolean = false;
  modelVisible: boolean = false;
  package = new QueryPackage();
  showModel() {
    this.modelVisible = true;
  }
  async saveModel() {
    //this.package = new QueryPackage();
    this.store.aggregation.name = this.package.name;
    this.package.version = this.store.aggregation.version;
    this.ds.setQueryObject(this.store.aggregation, this.package, 'aggregation');
    await this.ds.setModel(this.package);
    this.modelVisible = false;
  }
  cancelModel() {
    this.modelVisible = false;
  }
  select(item) {
    let cg = new ConditionGroup();
    let c = new Condition();
    c.Target = item;
    cg.conditions.push(c);
    this.store.aggregation.conditionpipe.push(cg);
    this.showconditionlist = false;
  }

  addstatistic() {
    this.store.aggregation.statistics.push(new Statistic());
  }
  calculateresult: string = '0';
  getstatisticValue(ro, name) {
    let sl: string[] = [];
    for (let key in ro) {
      if (key === name) {
        for (let k in ro[key])
          sl.push(name + '=>' + k + ':' + ro[key][k].toString());
      }
    }
    return sl;
  }
  getbucketsvalue(ro, name) {
    let r = {};
    for (let index = 0; index < ro[name]['buckets'].length; index++) {
      let element = ro[name]['buckets'][index];
      r[element['key']] = element['doc_count'];
    }
    return r;
  }
  getValues(ro, name) {
    for (let key in ro) {
      console.log(key);
      if (key === name) {
        return ro[key]['values'];
      }
    }
    return '0';
  }
  getValue(ro, name) {
    for (let key in ro) {
      console.log(key);
      if (key === name) {
        return ro[key]['value'];
      }
    }
    return '0';
  }
  getnextgroupstatisticname(stcarray: StatisticTerm[], name) {
    for (let index = 0; index < stcarray.length - 1; index++) {
      const element = stcarray[index];
      if (element.name == name) {
        return stcarray[index + 1].name;
      }
    }
    return undefined;
  }

  getgroupstatistic(ro, name, stcarray: StatisticTerm[]): any {
    // console.log('group');
    // console.log(ro);
    // console.log(name);
    let rd = {};
    let nn = this.getnextgroupstatisticname(stcarray, name);
    if (nn == undefined) {
      for (let index = 0; index < ro[name]['buckets'].length; index++) {
        let element = ro[name]['buckets'][index];
        rd[element['key']] = element['doc_count'];
      }
    } else {
      for (let index = 0; index < ro[name]['buckets'].length; index++) {
        let element = ro[name]['buckets'][index];
        let nextstep = this.getgroupstatistic(element, nn, stcarray);
        console.log(nextstep);
        for (let key in nextstep) {
          rd[element['key'] + ';' + key] = nextstep[key];
        }
      }
    }
    console.log(rd);
    return rd;
  }
  getstatistic(ro, name): { [key: string]: number } {
    console.log(ro);
    console.log(name);
    let rd: { [key: string]: number } = {};
    for (let key in ro) {
      if (key === name) {
        let bs = ro[key]['buckets'];
        console.log(bs);
        bs.forEach((element) => {
          rd[element['key']] = element['doc_count'];
        });
      }
    }
    console.log(rd);
    return rd;
  }
  getstatisticstring(dic: any): string[] {
    let s: string[] = [];
    for (let key in dic) s.push(key + ':' + dic[key].toString());
    return s;
  }
  isArray(obj) {
    return obj instanceof Array;
  }

  //判断是否为对象
  isObject(obj) {
    return obj instanceof Object;
  }
  aggResult: string[] = [];
  combinedResult = [];
  flatObject(obj): string[] {
    let rs: string[] = [];
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const element = obj[key];
        if (this.isObject(element)) {
          let or = this.flatObject(element);

          or.forEach((x) => {
            console.log(key + '.' + x);
            rs.push(key + '.' + x);
          });
        } else {
          let rstring = key + ':' + element.toString();

          rs.push(rstring);
        }
      }
    }
    return rs;
  }
  flat(collection: any[]): string[] {
    if (collection === undefined) return [];
    let rs: string[] = [];
    for (let v of collection) {
      console.log(v);
      let r = this.flatObject(v);
      console.log(r);
      rs = [...rs, ...r];
    }
    return rs;
  }
  includeCombine() {
    this.store.aggregation.statistics.forEach((s) => {
      s.terms.forEach((v) => {
        if (v.statistictype.startsWith('联合分组')) return true;
      });
    });
    return false;
  }
  exportCombine() {
    if (this.combinedResult.length > 0) {
      let s = this.ds.getCsv(this.combinedResult, undefined);

      let blob = new Blob([s], {
        type: 'text/plain;charset=utf-8',
      });
      fileSaver.saveAs(blob, this.store.aggregation.name + '.aggregation.csv');
    }
  }
  async aggregate() {
    if (
      this.store.aggregation.statistics.filter(
        (v) =>
          v.terms.filter((t) => t.name === undefined || t.name.trim() === '')
            .length > 0
      ).length > 0
    ) {
      notify('每个统计项都需要给名字，名字不能为空', 'error', 600);
      return;
    }
    console.log('start aggregate');
    let result: any[] = [];
    let exp = this.store.aggregation.expression;

    // for (let i = 0; i < this.current.statistics.length; i++) {
    let r = await this.ds.aggregate('mr', this.store.aggregation);

    console.log(this.store.aggregationresult.statisticResult);
    this.combinedResult = this.store.aggregationresult.combined;
    this.aggResult = this.flat(this.store.aggregationresult.statisticResult);

    this.store.aggregationresult.statisticResult.forEach((rs) => {
      for (const key in rs) {
        console.log(key);
        const element = rs[key];
        if (
          //element is a array
          typeof element != 'undefined' &&
          typeof element != 'object' &&
          typeof element != 'function'
        ) {
          //this.statisticResult.push(key + ":" + element.toString());
          var rstr = new RegExp(key, 'g');
          exp = exp.replace(rstr, element);
        } else {
          // is a object
          for (const vkey in element) {
            var rstr = new RegExp(key + '.' + vkey, 'g');
            exp = exp.replace(rstr, element[vkey]);
          }
        }
      }
    });

    console.log(exp);
    console.log(this.calculateresult);
    this.calculateresult = eval(exp);
    this.refreshNameList();
    //this.store.aggregations = ro["aggregations"];
  }

  remove(item) {
    var i = this.store.aggregation.conditionpipe.findIndex((v) => v === item);
    if (i > -1) this.store.aggregation.conditionpipe.splice(i, 1);
  }
  closeConditionList() {
    if (!this.clickAddConditionButton) this.showconditionlist = false;
  }
  closeStatisticList() {
    if (!this.clickAddStatisticButton) this.showstatisticlist = false;
  }

  addconditiongroup() {
    console.log('object');
    let cg = new ConditionGroup();
    this.store.aggregation.conditionpipe.push(cg);
  }
  removeGroup(item) {
    this.store.aggregation.conditionpipe.splice(
      this.store.aggregation.conditionpipe.indexOf(item),
      1
    );
  }
  removeStatistic(item) {
    this.store.aggregation.statistics.splice(
      this.store.aggregation.statistics.indexOf(item),
      1
    );
  }
  createagg() {
    this.store.aggregation = new Aggregation();
    this.combinedResult = [];
  }

  saveagg() {
    this.popupVisible = true;
  }
  confirm() {
    if (
      this.store.aggregation.name === undefined ||
      this.store.aggregation.name === ''
    ) {
      notify('未输入名称', 'error', 600);
    } else {
      let blob = new Blob([JSON.stringify(this.store.aggregation)], {
        type: 'text/plain;charset=utf-8',
      });
      fileSaver.saveAs(blob, this.store.aggregation.name + '.aggregation.json');
    }
    this.popupVisible = false;
  }
  cancel() {
    this.popupVisible = false;
  }
  handleFileSelect(evt) {
    var files = evt.target.files;
    var f = files[0];
    var reader = new FileReader();

    reader.readAsText(f);
    reader.onload = ((f) => {
      return (e) => {
        let agg = JSON.parse(e.target.result);
        this.store.aggregation = this.ds.cloneAggregation(agg);
      };
    })(f);
  }
  haveResult() {
    return (
      this.store.aggregation.expression !== undefined &&
      this.store.aggregation.expression.trim() !== ''
    );
  }
  export() {
    if (this.aggResult.length > 0) {
      //let s = this.ds.getCsv(this.aggResult);
      let s = '';
      if (
        this.haveResult() &&
        this.calculateresult !== undefined &&
        this.calculateresult.trim() !== ''
      )
        s = '统计结果,' + this.calculateresult + '\n';
      this.aggResult.forEach((v) => {
        s += v.replace(':', ',') + '\n';
      });

      let blob = new Blob([s], {
        type: 'text/plain;charset=utf-8',
      });
      fileSaver.saveAs(blob, this.store.aggregation.name + '.agg.csv');
    }
  }
  getname(value) {
    let ei = value.indexOf('.');
    return value.substring(0, ei);
  }
  statisticNameList: string[] = [];
  refreshNameList() {
    this.statisticNameList = [];
    this.aggResult.forEach((v) => {
      let n = this.getname(v);
      if (!this.statisticNameList.includes(n)) this.statisticNameList.push(n);
    });
  }
  currentChartName: string;
  chartData: DataPoint[] = [];
  refreshChart() {
    this.chartData = [];
    console.log(this.aggResult);
    this.aggResult.forEach((r) => {
      console.log(r);
      console.log(this.currentChartName + '.');
      if (r.startsWith(this.currentChartName + '.')) {
        let ei = r.indexOf(':');
        let lab = r.substring(this.currentChartName.length + 1, ei + 1);
        let v = Number(r.substring(ei + 1));
        console.log(r);
        console.log(this.currentChartName.length + 1);
        console.log(ei + 1);
        console.log(lab);
        console.log(v);
        this.chartData.push(new DataPoint(lab, v));
      }
    });
    console.log(this.chartData);
  }
}
